/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "timeline_msdp_client_impl.h"
#include <string>
#include <cerrno>
#include <sys/epoll.h>
#include <sys/timerfd.h>
#include <linux/netlink.h>
#include <unistd.h>
#include <errors.h>
#include "dummy_values_bucket.h"
#include "timeline_common.h"

using namespace OHOS::NativeRdb;
namespace OHOS {
namespace Msdp {
namespace {
static const int ERR_OK = 0;
static const int ERR_NG = -1;
}

ErrCode TimelineMsdpClientImpl::InitMsdpImpl()
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");
    if (timelineInterface_ == nullptr) {
        timelineInterface_ = std::make_unique<TimelineInterface>();
        if (timelineInterface_ == nullptr) {
            TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "get msdp module instance failed");
            return ERR_NG;
        }
    }

    timelineInterface_->Enable();

    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "exit");
    return ERR_OK;
}

ErrCode TimelineMsdpClientImpl::RegisterImpl(CallbackManager callback)
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");
    callbacksMgr_ = callback;

    RegisterMsdp();

    return ERR_OK;
}

ErrCode TimelineMsdpClientImpl::ImplCallback(TimelineDataUtils::TimelineData& data)
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");
    callbacksMgr_(data);

    return ERR_OK;
}

ErrCode TimelineMsdpClientImpl::EnableMsdp()
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");
    int32_t ret = timelineInterface_->Enable();
    if (ret < 0) {
        TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "Enable Msdp failed");
        return ERR_NG;
    }

    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "exit");
    return ERR_OK;
}

ErrCode TimelineMsdpClientImpl::DisableMsdp()
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");
    int32_t ret = timelineInterface_->Disable();
    if (ret < 0) {
        TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "Disable Msdp failed");
        return ERR_NG;
    }

    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "exit");
    return ERR_OK;
}

ErrCode TimelineMsdpClientImpl::RegisterMsdp()
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");
    if (timelineInterface_ != nullptr) {
        TimelineInterface::CallbackImpl callback = std::bind(&TimelineMsdpClientImpl::MsdpCallback, this, std::placeholders::_1);
        timelineInterface_->RegisterCallback(callback);
    }

    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "exit");
    return ERR_OK;
}

ErrCode TimelineMsdpClientImpl::UnregisterMsdp(void) const
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");
    int32_t ret = timelineInterface_->UnregisterCallback();
    if (ret < 0) {
        TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "unregister Msdp failed");
        return ERR_NG;
    }

    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "exit");
    return ERR_OK;
}

int32_t TimelineMsdpClientImpl::MsdpCallback(TimelineDataUtils::TimelineData& data)
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");
    SaveObserverData(data);
    if (notifyManagerFlag_) {
        ImplCallback(data);
        notifyManagerFlag_ = false;
    }

    return ERR_OK;
}

TimelineDataUtils::TimelineData TimelineMsdpClientImpl::SaveObserverData(TimelineDataUtils::TimelineData& data)
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");
    for (auto iter = timelineDataMap_.begin(); iter != timelineDataMap_.end(); ++iter) {
        if (iter->first == data.area) {
            iter->second = data.value;
            notifyManagerFlag_ = true;
            return data;
        }
    }

    timelineDataMap_.insert(std::make_pair(data.area, data.value));
    notifyManagerFlag_ = true;

    return data;
}

std::map<TimelineDataUtils::TimelineArea, TimelineDataUtils::TimelineValue> TimelineMsdpClientImpl::GetObserverData() const
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");
    return timelineDataMap_;
}

void TimelineMsdpClientImpl::GetTimelineTimestamp()
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");

    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "exit");
}

void TimelineMsdpClientImpl::GetLongtitude()
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");

    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "exit");
}

void TimelineMsdpClientImpl::GetLatitude()
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");

    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "exit");
}
}
}
